﻿using CefSharp;
using CefSharp.Wpf;
using DreamSpace.Net;
using DreamSpace.Net.ScriptEngines;
using ICE;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Windows;
using V8.Net;

namespace DreamSpace.Studio
{
    public partial class App : Application
    {
        /// <summary>
        /// The DSServer encapsulates the core JavaScript engine used for both desktop client applications, and server side services.
        /// A desktop applications simply contain both the Google CEF viewer portion, and the DreamSpace Server in one.
        /// The CEF implementation (an embedded browser) contains the UI logic only, and pipes communication to the internal V8.NET server.
        /// This keeps database, file system, and other non-browser related activities in a proper supported environment for best compatibility when
        /// developing network related applications.
        /// </summary>
        public static DreamSpaceServer DSServer { get; private set; }

        /// <summary>
        /// Represents a single script engine host (using V8.NET as the default).
        /// </summary>
        public static IServerHost<IScriptEngine> ServerHost { get; private set; }

        /// <summary>
        /// A reference to the Chrome Embedded Framework WPF control (CEFSharp).
        /// </summary>
        public static WebView WebViewer { get; private set; }

        public static readonly string[] DreamSpaceJSDebugManifest = new string[] 
        {
            //??"DreamSpaceJS/JQuery/jquery.js",
            "DreamSpaceJS/Linq/linq.js",
            "DreamSpaceJS/Bootstrap/js/bootstrap.js",
            "DreamSpaceJS/HostBridge.js",
            "DreamSpaceJS/HostBridge.ICE.js",
            "DreamSpaceJS/DreamSpace.Common.js",
            "DreamSpaceJS/DreamSpace.UI.js",
            "DreamSpaceJS/Bootstrap.js",
            "DreamSpaceJS/DreamSpaceServer.js",
            "app.js"
        };

        public static readonly string[] DreamSpaceJSReleaseManifest = new string[] 
        {
            //??"DreamSpaceJS/JQuery/jquery.min.js",
            "DreamSpaceJS/Linq/linq.min.js",
            "DreamSpaceJS/Bootstrap/js/bootstrap.min.js",
            "DreamSpaceJS/HostBridge.min.js",
            "DreamSpaceJS/HostBridge.ICE.min.js",
            "DreamSpaceJS/DreamSpace.Common.min.js",
            "DreamSpaceJS/DreamSpace.UI.min.js",
            "DreamSpaceJS/Bootstrap.min.js",
            "DreamSpaceJS/DreamSpaceServer.min.js",
            "app.min.js"
        };

        public static string Title = "DreamSpace Studio";
        public static string StartupDirectory { get; private set; }
        public static string StartupFile { get; private set; }

        protected override void OnStartup(StartupEventArgs e) // Command argument order: [Title [Working Directory [Startup JS File]]]
        {
            base.OnStartup(e);

            DSServer = new DreamSpaceServer();
            ServerHost = DSServer.CreateV8ServerHost();

            WebViewer = new WebView("", new BrowserSettings { });

            ICEController.Initialize();

            // ... process any arguments (this should be done after all global/static objects are created) ...

            if (e.Args.Length > 0 && !string.IsNullOrEmpty(e.Args[0]))
                Title = e.Args[0];

            if (e.Args.Length > 1)
            {
                StartupDirectory = e.Args[1];
                if (!string.IsNullOrEmpty(StartupDirectory))
                {
                    if (!Directory.Exists(StartupDirectory))
                        throw new DirectoryNotFoundException("The location '" + StartupDirectory + "' does not exist, or is not accessible.");
                    Directory.SetCurrentDirectory(StartupDirectory);
                }
            }

            if (e.Args.Length > 2)
                StartupFile = e.Args[2];
        }

        protected override void OnExit(ExitEventArgs e)
        {
            ICEController.Shutdown(); // (waits for all channel threads to terminate or timeout before returning)
            base.OnExit(e);
        }

        public static void LoadServerJSLibraries()
        {
            // ... load the DreamSpaceJS core files, and optional startup application file ...
#if DEBUG
            string[] dsjsManifest = DreamSpaceJSDebugManifest;
#else
                string[] dsjsManifest = DreamSpaceJSReleaseManifest;
#endif
            string dsjsLibraryFile = "";
            try
            {
                // ... load and execute each script file (note: for server only - the web UI will loaded the default page, which will contain the libraries) ...

                for (var i = 0; i < dsjsManifest.Length; i++)
                    App.ServerHost.LoadScript(dsjsLibraryFile = dsjsManifest[i], null, true);

                if (!string.IsNullOrEmpty(StartupFile))
                    App.ServerHost.LoadScript(dsjsLibraryFile = StartupFile, null, true);
            }
            catch (Exception ex)
            {
                throw new FileLoadException("Could not load or compile a required JS library: '" + dsjsLibraryFile + "'", ex);
            }
        }
    }
}
